package com.zzyl.nursing.service.impl;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zzyl.common.exception.base.BaseException;
import com.zzyl.common.utils.CodeGenerator;
import com.zzyl.nursing.domain.*;
import com.zzyl.nursing.dto.CheckInApplyDto;
import com.zzyl.nursing.dto.CheckInContractDto;
import com.zzyl.nursing.dto.CheckInElderDto;
import com.zzyl.nursing.mapper.*;
import com.zzyl.nursing.service.ICheckInService;
import com.zzyl.nursing.vo.CheckInConfigVo;
import com.zzyl.nursing.vo.CheckInDetailVo;
import com.zzyl.nursing.vo.CheckInElderVo;
import com.zzyl.nursing.vo.ElderFamilyVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.List;

/**
 * 入住Service业务层处理
 * 
 * @author ruoyi
 * @date 2025-07-23
 */
@Service
public class CheckInServiceImpl extends ServiceImpl<CheckInMapper, CheckIn> implements ICheckInService
{
    @Autowired
    private CheckInMapper checkInMapper;

    @Autowired
    private CheckInConfigMapper checkInConfigMapper;


    @Autowired
    private ElderMapper elderMapper;

    @Autowired
    private ContractMapper contractMapper;


    @Autowired
    private BedMapper bedMapper;



    /**
     * 查询入住
     * 
     * @param id 入住主键
     * @return 入住
     */
    @Override
    public CheckIn selectCheckInById(Long id)
    {
        return getById(id);
    }

    /**
     * 查询入住列表
     * 
     * @param checkIn 入住
     * @return 入住
     */
    @Override
    public List<CheckIn> selectCheckInList(CheckIn checkIn)
    {
        return checkInMapper.selectCheckInList(checkIn);
    }

    /**
     * 新增入住
     * 
     * @param checkIn 入住
     * @return 结果
     */
    @Override
    public int insertCheckIn(CheckIn checkIn)
    {
        return save(checkIn) ? 1 : 0;
    }

    /**
     * 修改入住
     * 
     * @param checkIn 入住
     * @return 结果
     */
    @Override
    public int updateCheckIn(CheckIn checkIn)
    {
        return updateById(checkIn) ? 1 : 0;
    }

    /**
     * 批量删除入住
     * 
     * @param ids 需要删除的入住主键
     * @return 结果
     */
    @Override
    public int deleteCheckInByIds(Long[] ids)
    {
        return removeByIds(Arrays.asList(ids)) ? 1 : 0;
    }

    /**
     * 删除入住信息
     * 
     * @param id 入住主键
     * @return 结果
     */
    @Override
    public int deleteCheckInById(Long id)
    {
        return removeById(id) ? 1 : 0;
    }

    /**
     * 申请入住（新增）
     *
     * @param checkInApplyDto
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void apply(CheckInApplyDto checkInApplyDto) {

        //1、入住申请 验证老人是否已入住   系统检查该老人是否已经存在入住记录。

        LambdaUpdateWrapper<Elder> elderLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        //根据身份证号进行比对
        LambdaUpdateWrapper<Elder> eq = elderLambdaUpdateWrapper.eq(Elder::getIdCardNo, checkInApplyDto.getCheckInElderDto().getIdCardNo())
                .eq(Elder::getStatus, 1);//状态是否为1
        if (ObjectUtils.isEmpty(eq)){ // 如果查询结果为空，则说明该老人不存在
            throw new BaseException("老人已经存在");//自定义异常
        }

        //如果不存在就继续执行下面操作
        //2、更新床位状态为已入住  将分配给该老人的床位状态更新为“已入住”。
        Bed bed = bedMapper.selectBedById(checkInApplyDto.getCheckInConfigDto().getBedId());
        bed.setBedStatus(1);//已入住
        bedMapper.updateBed(bed);



        //3、新增或更新老人信息   如果是新老人，则新增老人信息；如果是已有老人，则更新其信息。
        Elder elder = insertOrUpdateElder(checkInApplyDto, bed);

        //4、新增签约办理  为老人办理入住签约手续，记录签约信息。
        insertContract(checkInApplyDto,elder);

        //5、新增入住信息  记录老人的入住信息，如入住时间、床位号等。
        CheckIn checkIn = insertCheckIn(checkInApplyDto, elder);


        //6、新增入住配置  配置老人的入住相关设置，如护理级别、饮食偏好等。
        insertCheckInConfig( checkIn,  checkInApplyDto);

        //7、老人已入住   如果老人已存在入住记录，则提示“老人已入住”。




    }

    /**
     * 查询入住详情
     *
     * @param id
     * @return
     */
    @Override
    public CheckInDetailVo detail(Long id) {
        /**  json响应数据
         {
         "msg": "操作成功",
         "code": 200,
         "data": {
         "checkInElderVo": {
         "id": 326,
         "name": "李天龙",
         "idCardNo": "132123195612131234",
         "birthday": "2024-08-11",
         "sex": 1,
         "phone": "13211223322",
         "address": "北京市昌平区",
         "image": "https://itheim.oss-cn-beijing.aliyuncs.com/85f734bd-26be-4be1-8086-0ffae0b2374d.png",
         "idCardNationalEmblemImg": "https://itheim.oss-cn-beijing.aliyuncs.com/843b67d3-1061-4a27-89e1-a7974c826c36.jpg",
         "idCardPortraitImg": "https://itheim.oss-cn-beijing.aliyuncs.com/00fd6a90-d982-4981-92c8-5c29ebb276d9.jpg",
         "age": 67
         },
         "elderFamilyVoList": [
         {
         "name": "李彤",
         "phone": "13211223311",
         "kinship": "0"
         }
         ],
         "checkInConfigVo": {
         "createBy": "1",
         "createTime": "2024-08-26 15:44:08",
         "updateTime": "2024-08-26 07:44:08",
         "id": 2,
         "checkInId": 6,
         "nursingLevelId": 77,
         "nursingLevelName": "一级护理等级",
         "feeStartDate": "2024-08-26 00:00:00",
         "feeEndDate": "2024-08-31 00:00:00",
         "deposit": 3000.00,
         "nursingFee": 2000.00,
         "bedFee": 6000.00,
         "insurancePayment": 1.00,
         "governmentSubsidy": 1.00,
         "otherFees": 1.00,
         "sortOrder": 0,
         "startDate": "2024-08-26 00:00:00",
         "endDate": "2024-09-30 00:00:00",
         "bedNumber": "106-1"
         },
         "contract": {
         "createBy": "1",
         "createTime": "2024-08-26 15:44:08",
         "updateTime": "2024-08-26 07:44:08",
         "id": 2,
         "elderId": 326,
         "contractName": "李天龙的入住合同",
         "contractNumber": "HT202408261544080001",
         "agreementPath": "https://itheim.oss-cn-beijing.aliyuncs.com/0908707d-7ad4-4d30-ad7d-efdb9c946015.jpg",
         "thirdPartyPhone": "13211223311",
         "thirdPartyName": "李彤",
         "elderName": "李天龙",
         "startDate": "2024-08-26 00:00:00",
         "endDate": "2024-09-30 00:00:00",
         "status": 0,
         "signDate": "2024-08-26 00:00:00",
         "sortOrder": 0
         }
         }
         }
         */
        //1.0 先查询入住信息
        CheckIn checkIn = checkInMapper.selectById(id);
        //根据id查询入住信息
        //1首先查询老人信息
        Elder elder = elderMapper.selectById(checkIn.getElderId());
        CheckInElderVo checkInElderVo = new CheckInElderVo();
        BeanUtils.copyProperties(elder,checkInElderVo);
        //1.1 需要截取年龄的信息
        String idCardNo = elder.getIdCardNo();
        Integer age = getElderAge(idCardNo);
        checkInElderVo.setAge(age);

        //2.查询合同
        //根据老人id信息，查询合同信息，加上条件
        Contract contract = contractMapper.selectOne(Wrappers.<Contract>lambdaQuery().eq(Contract::getElderId, checkIn.getElderId()));


        //3. 查询入住配置
//        CheckInConfig checkInConfig = checkInConfigMapper.selectById(id);
        CheckInConfigVo checkInConfigVo = new CheckInConfigVo();
        CheckInConfig checkInConfig = checkInConfigMapper.selectOne(Wrappers.<CheckInConfig>lambdaQuery().eq(CheckInConfig::getCheckInId, checkIn.getId()));
        BeanUtils.copyProperties(checkInConfig,checkInConfigVo);

        //根据入住信息表。获取入住开始时间，入住结束时间，入住床位
        checkInConfigVo.setStartDate(checkIn.getStartDate());
        checkInConfigVo.setEndDate(checkIn.getEndDate());
        checkInConfigVo.setBedNumber(checkIn.getBedNumber());


        //4. 查询家属列表
        String remark = checkIn.getRemark();
        //把json数据转成java对象
        List<ElderFamilyVo> elderFamilyVoList = JSON.parseArray(remark, ElderFamilyVo.class);


        //5. 整合数据
        return new CheckInDetailVo(checkInElderVo,elderFamilyVoList,checkInConfigVo,contract);
    }

    /**
     * 根据身份账号获取当前年龄
     */
    private Integer getElderAge(String idCardNo) {


        //1.2 获取年月日
        String birthday = idCardNo.substring(6,14);//截取年龄
        String year = birthday.substring(0,4);
        String month = birthday.substring(4,6);
        String day = birthday.substring(6,8);
        //当前时间,使用Loaldatetime, 并获取当前时间的年月日
        LocalDateTime localDateTime = LocalDateTime.now();
       //把localDateTime转成字符串
        String now = localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        Integer nowYear = Integer.valueOf(now.substring(0,4));
        Integer nowMonth = Integer.valueOf(now.substring(5,7));
        Integer nowDay = Integer.valueOf(now.substring(8,10));

        Integer age = nowYear - Integer.parseInt(year);

        if (nowMonth>Integer.valueOf(month)){//当前月份大于生日的月份，说明还没到今年生日，就减去一岁
            age-=1;
        } else if (nowMonth.equals(Integer.valueOf(month))) { //如果相等，就判断天数
            if (nowDay >Integer.valueOf(day)){
                age-=1;
            }
        }
        return age;
    }


    /**
     * 新增入住配置
     */
    private void insertCheckInConfig(CheckIn checkIn, CheckInApplyDto checkInApplyDto) {

        CheckInConfig checkInConfig = new CheckInConfig();
        BeanUtils.copyProperties(checkInApplyDto.getCheckInConfigDto(),checkInConfig);
        checkInConfig.setCheckInId(checkIn.getId());
        checkInConfigMapper.insert(checkInConfig);



    }

    /**
     * 新增入住信息
     */
    private CheckIn insertCheckIn(CheckInApplyDto checkInApplyDto, Elder elder) {

        CheckIn checkIn = new CheckIn();
        checkIn.setElderId(elder.getId());
        checkIn.setElderName(elder.getName());
        checkIn.setIdCardNo(elder.getIdCardNo());
        checkIn.setNursingLevelName(checkInApplyDto.getCheckInConfigDto().getNursingLevelName());
        checkIn.setStartDate(checkInApplyDto.getCheckInConfigDto().getStartDate());
        checkIn.setEndDate(checkInApplyDto.getCheckInConfigDto().getEndDate());
        checkIn.setBedNumber(elder.getBedNumber());
        checkIn.setRemark(JSON.toJSONString(checkInApplyDto.getElderFamilyDtoList()));
        checkIn.setStatus(0);

        checkInMapper.insert(checkIn);
        return checkIn;


    }

    /**
     * 新增签约办理
     */
    private void insertContract(CheckInApplyDto checkInApplyDto, Elder elder) {
        Contract contract = new Contract();//签约办理
        CheckInContractDto checkInContractDto = checkInApplyDto.getCheckInContractDto();
        BeanUtils.copyProperties(checkInContractDto,contract);
        //生成合同编号
        String contractNo = "ZZYL"+CodeGenerator.generateContractNumber();
        contract.setContractNumber(contractNo);

        contract.setElderId(Integer.valueOf(elder.getId()+""));
        contract.setElderName(elder.getName());

        LocalDateTime checkInStartTime = checkInApplyDto.getCheckInConfigDto().getStartDate();
        LocalDateTime checkInEndTime = checkInApplyDto.getCheckInConfigDto().getEndDate();
        Integer status = checkInStartTime.isBefore(LocalDateTime.now()) ? 1 : 0;
        contract.setStatus(status);
        contract.setStartDate(checkInStartTime);
        contract.setEndDate(checkInEndTime);
        contractMapper.insert(contract);


    }

    /**
     * 新增或更新老人信息
     */
    private Elder insertOrUpdateElder(CheckInApplyDto checkInApplyDto,Bed bed) {
        //老人信息
        CheckInElderDto newElder = checkInApplyDto.getCheckInElderDto();
        Elder elder = new Elder();
        BeanUtils.copyProperties(newElder,elder);
        elder.setBedNumber(bed.getBedNumber());
        elder.setBedId(bed.getId());
        elder.setStatus(1);

        //要看看是否新增还是修改


        //根据身份证号进行比对
        LambdaQueryWrapper<Elder> eq = Wrappers.<Elder>lambdaQuery().eq(Elder::getIdCardNo, checkInApplyDto.getCheckInElderDto().getIdCardNo())
                .ne(Elder::getStatus, 1);//状态是否为1,
        Elder elder1 = elderMapper.selectOne(eq);//selectOne作用：查询一条记录
        if (ObjectUtils.isEmpty(elder1)){
            //新增
            elderMapper.insert(elder);

        }else{
            //修改
            elderMapper.updateById(elder);

        }
        return elder;

    }


}
